Skip to main content

Dynamic HTML

A user doesn't need any app installed to interact with sliders in your notebook

tip

Please read the manual carefully.

This is a dynamic version of the Static HTML exporter, designed to recreate the full interactivity of normal notebooks.

Use Cases

  • All use cases from Static HTML
  • Demonstration projects
  • Live animations of physical processes
  • Interactive presentations / lecture notes

How It Works

To make the system more general and support features like ManipulatePlot, Manipulate, combinations of InputRange, InputButton, Offload, FrontSubmit, EmitSound, and many more are abstracted from their controlling elements. The system purely analyzes events and symbol mutations.

Your dynamic system must follow a call and response architecture. That means it must generate events (via user interaction or code) and produce a response (e.g., symbol mutation or FrontSubmit).

note

TL;DR: We record calculated data for all possible combinations of input elements and store them in a large table. See the How to Use section.

Details

Analysis

To analyze the bindings between input elements, symbols, and commands executed by the Wolfram Kernel, we inject a spy into the evaluation kernel by modifying DownValues of WLJS I/O symbols. This captures symbol mutations triggered by external events and submitted commands like FrontSubmit or EmitSound. For instance, PlotlyAnimate also uses FrontSubmit and can be tracked.

After capturing all data, it's forwarded to samplers or virtual state machines.

Processing

We use different processing techniques based on the use case, selected automatically. These are known as Black Boxes or virtual machines.

Similar to airplane black boxes that record all data for post-crash analysis.

There are three types of virtual machines (automatically chosen) with fun names:

State Machine

This tracks system state based on input element combinations. It samples all possible states and dispatches the corresponding symbol mutations.

Pavlov Machine

Like Pavlov's Dog, it doesn't track state but records event → FrontSubmit pairs.

Animation Machine

Detects series of symbol mutations from the same event, typically used for animations (e.g., via AnimationFrameListener). It tracks only abstract frame numbers.

We're planning to add small CNNs to compress mutations more efficiently in the future.

How to Use

Please follow the steps below:

Prepare the Notebook

Connect to the Wolfram Kernel and evaluate your dynamics. Minimize the number of input elements and their states. For example, avoid 3 sliders (InputRange) with 100 steps each. For ManipulatePlot, explicitly set step values. Limit the number and complexity of dynamic symbols.

If you're recording an animation with AnimationFrameListener, start it right before the next step. Note: SetInterval effects are not captured.

Example using a single slider:

ManipulatePlot[{
Sum[(Sin[2π(2j - 1) x])/(2j - 1), {j, 1, n}],
Sum[(Cos[2π(2j - 1) x])/(2j - 1), {j, 1, n}]
} // Re, {x, -1, 1}, {n, 1, 10, 1}]

Sniffing Phase

Click ShareDynamic Notebook to begin recording. A widget will appear in the top-right corner.

info

If you're recording an animation, evaluate the cell, wait for your desired number of frames, then click Continue in the widget.

Move each slider across its full range. This is necessary, as the sampling phase will only use values seen during sniffing.

tip

For multiple inputs (2–3 sliders), move each fully once. Cross-combinations are not needed—they will be sampled recursively.

Sampling Phase (State Machine)

Now the system automatically samples all input combinations. This may take time, depending on state count and symbol complexity.

This is the final stage. Afterward, the notebook is exported with the collected data to your drive. Click Continue.

Result

File sizes typically range from 7–20 MB, or 3–15 MB with CDN settings (see Static HTML). The example above is just 165 kB uncompressed and 50 kB compressed.

The result is a fully interactive widget, working offline without an internet connection or the Wolfram Kernel ✨

note

This works with Slides and WLX cells too.

What Else Can Be Exported?

Here's a list of supported exports:

State Machine

Manipulate[Series[Sin[x], {x, 0, n}], {n, 1, 10, 1}]
ManipulatePlot[f[w x], {x, -10, 10}, {w, 0, 10}, {f, {Sinc, Sin}}]

Or custom dynamics:

radius = 1.0;
Graphics[{Hue[radius // Offload], Disk[{0, 0}, radius // Offload]}, ImageSize -> Small]

EventHandler[InputRange[0, 1, 0.1], (radius = #)&]

Pavlov Machine

EventHandler[InputButton[], (Sound[SoundNote["C5"]] // EmitSound)&]

Even Plotly:

p = Plotly[{<|
"values" -> {19, 26, 10},
"labels" -> {"Residential", "Non-Residential", "Utility"},
"type" -> "pie"
|>}]

EventHandler[InputRange[0, 100, 10], PlotlyAnimate[p,
<|"data" -> {<|"values" -> {19, 26, #}|>},
"traces" -> {0}
|>, <||>]&
]

Animation Machine

Example: balls falling down a staircase

Online Examples

Check out some interactive examples from our blog and demo projects: